function [w,b] = psvm(X,Y,C)

if (nargin < 2)
    error('Not enough arguments!');
end

[n,d] = size(X);
l = size(Y,1);
Xt = X(1:l,:);

if (nargin == 2)
    disp('Training hard-margin svm...');
    cvx_begin quiet
    cvx_solver sedumi
    variable w(d,1);
    variable b;
    minimize (w'*w);
    Y.*(Xt*w+b) >= ones(l,1);
    cvx_end
    fprintf('Status:\t%s\n',cvx_status);
    fprintf('Value:\t%f\n',cvx_optval);
    fprintf('Time:\t%f\n',cvx_cputime);
    fprintf('Iters:\t%d\n',cvx_slvitr);
    fprintf('\n');
else
    disp('Training soft-margin svm...');
    cvx_begin
    cvx_solver sedumi
    variable w(d,1)
    variable b
    variable del(l,1) nonnegative
    minimize (w'*w+2*C*sum(del));
    Y.*(Xt*w+b)+del-ones(l,1) >= 0;
    cvx_end
    fprintf('Status:\t%s\n',cvx_status);
    fprintf('Value:\t%f\n',cvx_optval);
    fprintf('Time:\t%f\n',cvx_cputime);
    fprintf('Iters:\t%d\n',cvx_slvitr);
    fprintf('\n');
end
end